package com.joysuch.wwyt.patrol.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.base.Splitter;
import com.joysuch.wwyt.bp.repository.BpDepartDao;
import com.joysuch.wwyt.bp.service.BPInspectPointTypeService;
import com.joysuch.wwyt.common.constant.Constant;
import com.joysuch.wwyt.core.bean.ResultDto;
import com.joysuch.wwyt.core.bean.SimpleListBean;
import com.joysuch.wwyt.core.bean.vo.KeyValueVO;
import com.joysuch.wwyt.core.common.ajax.ResultBean;
import com.joysuch.wwyt.core.common.util.SimpleDateFormatCache;
import com.joysuch.wwyt.core.enums.DeleteFlag;
import com.joysuch.wwyt.core.enums.Status;
import com.joysuch.wwyt.core.exception.ApiBusinessException;
import com.joysuch.wwyt.core.repository.BaseUserDao;
import com.joysuch.wwyt.core.service.BaseRoleDataAuthService;
import com.joysuch.wwyt.core.service.BaseTypeGroupItemService;
import com.joysuch.wwyt.core.support.Context;
import com.joysuch.wwyt.patrol.entity.PatrolCheckPlan;
import com.joysuch.wwyt.patrol.entity.PatrolExceptionNotify;
import com.joysuch.wwyt.patrol.entity.PatrolPlanPointMapping;
import com.joysuch.wwyt.patrol.entity.bean.PatrolCheckPlanBean;
import com.joysuch.wwyt.patrol.entity.bean.PatrolCheckPlanPointBean;
import com.joysuch.wwyt.patrol.entity.bean.PatrolPlanExceptionNotifyBean;
import com.joysuch.wwyt.patrol.entity.dto.CheckPlanPageDto;
import com.joysuch.wwyt.patrol.entity.vo.CheckPlanDetailPointVo;
import com.joysuch.wwyt.patrol.entity.vo.CheckPlanDetailVo;
import com.joysuch.wwyt.patrol.entity.vo.CheckPlanPageVo;
import com.joysuch.wwyt.patrol.enums.CycleType;
import com.joysuch.wwyt.patrol.enums.CycleUnit;
import com.joysuch.wwyt.patrol.mapper.PatrolCheckPlanMapper;
import com.joysuch.wwyt.patrol.mapper.PatrolPlanPointMappingMapper;
import com.joysuch.wwyt.patrol.service.*;
import com.joysuch.wwyt.util.SnowFlakeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

import static com.joysuch.wwyt.common.constant.Constant.SPLIT_COMMA;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author zr
 * @since 2022-02-28
 */
@Service
@Slf4j
public class PatrolCheckPlanServiceImpl extends ServiceImpl<PatrolCheckPlanMapper, PatrolCheckPlan> implements PatrolCheckPlanService {

    @Autowired
    private PatrolCheckPlanMapper patrolCheckPlanMapper;
    @Autowired
    private PatrolExceptionNotifyService patrolExceptionNotifyService;
    @Autowired
    private PatrolPlanPointMappingService patrolPlanPointMappingService;
    @Autowired
    private PatrolPlanPointMappingMapper patrolPlanPointMappingMapper;
    @Autowired
    private BPInspectPointTypeService bpInspectPointTypeService;
    @Autowired
    private PatrolCheckItemService patrolCheckItemService;
    @Autowired
    private BpDepartDao bpDepartDao;
    @Autowired
    private PatrolCheckPointService patrolCheckPointService;
    @Autowired
    private BaseRoleDataAuthService baseRoleDataAuthService;
    @Autowired
    private BaseUserDao baseUserDao;
    @Autowired
    private BaseTypeGroupItemService baseTypeGroupItemService;
    @Autowired
    private PatrolTaskService patrolTaskService;


    @Override
    public List<PatrolCheckPlan> getEfficientPlans() {
        LambdaQueryWrapper<PatrolCheckPlan> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(PatrolCheckPlan::getDeleteFlag, DeleteFlag.EFFECTIVE.getCode());
        wrapper.eq(PatrolCheckPlan::getStatus, Constant.COMMON_SWITCH_ON);
        return patrolCheckPlanMapper.selectList(wrapper);
    }

    @Override
    public void savePlan(PatrolCheckPlanBean planBean) throws ApiBusinessException {
        //判断是否有重名,
        Long tenentId = Context.getCurrentTenantId();
        String orgCode = Context.getCurrentOrgCode();
        Long count = patrolCheckPlanMapper.judgeForName(planBean.getCheckPlanName(), tenentId, orgCode);
        if (0 != count) {
            throw new ApiBusinessException(Status.CHECK_PLAN_NAME_REPEAT, planBean.getCheckPlanName());
        }
        //先保存计划的基本配置
        PatrolCheckPlan plan = saveForPlan(planBean);
        //保存报警通知列表 待定
        /*saveForExceptionNotify(planId,planBean.getExceptionNotifyBeanList());*/
        //保存检查点列表
        saveForCheckPoint(plan.getId(), planBean.getPatrolCheckPlanPointBeanList());
        //判断是否立即推送
        String pushTaskNow = planBean.getPushTaskNow();
        if (Constant.COMMON_SWITCH_ON.equals(pushTaskNow)) {
            //推送任务
            patrolTaskService.producePatrolTask(plan.getId());
        }
    }

    /**
     * 新增计划时的保存
     *
     * @return plan的id
     */
    private PatrolCheckPlan saveForPlan(PatrolCheckPlanBean planBean) {
        PatrolCheckPlan plan = new PatrolCheckPlan();
        plan.setPlanName(planBean.getCheckPlanName())
                .setCheckTypeId(planBean.getCheckTypeId())
                .setResponsibleDept(planBean.getResponsibleDept())
                .setCycleType(planBean.getCycleType())
                .setCycleUnit(planBean.getCycleUnit())
                .setFrequencyInterval(planBean.getFrequencyInterval())
                .setPlanEndTime(planBean.getPlanEndTime())
                .setExceptionNotify(planBean.getExceptionNotify())
                .setAllowRepair(planBean.getAllowRepair())
                .setOrderCheck(planBean.getOrderCheck())
                .setSignAdvance(planBean.getSignAdvance())
                .setAdvanceTime(planBean.getAdvanceTime())
                .setPatrolMode(planBean.getPatrolMode())
                .setPushTaskNow(planBean.getPushTaskNow())
                .setStatus(Constant.COMMON_SWITCH_ON)
                .setPlanVersion(0L)
                .setBatchNo(SnowFlakeUtil.getCheckPlanId().toString())
                .setDeviceStopAutoProcess(planBean.getDeviceStopAutoProcess());
        //获取计划的开始时间
        Date planStartTime = getPlanStartTime(planBean);
        plan.setPlanStartTime(planStartTime);
        //将前端传入的时间段转为string保存
        String planPeriod = getPlanPeriod(planBean);
        plan.setPeriod(planPeriod);
        //将userId数组转为string存储
        String planCheckUserIds = getPlanCheckUserIds(planBean);
        plan.setCheckUserIds(planCheckUserIds);
        //获取计划允许补检的时间
        Integer planAllowRepairTime = getPlanAllowRepairTime(planBean);
        plan.setSupplementaryInspectionTime(planBean.getSupplementaryInspectionTime());
        plan.setCustomizeSupplementaryInspection(planBean.getCustomizeSupplementaryInspection());
        plan.setDelayMinute(planAllowRepairTime);
        //报存文案描述
        String planCycleDesc = getPlanCycleDesc(planBean);
        plan.setCycleDesc(planCycleDesc);
        patrolCheckPlanMapper.insert(plan);
        return plan;
    }

    /**
     * 按照前端传入规则将任务开始日期转为后端需要的时间
     *
     * @param planBean
     * @return
     */
    private Date getPlanStartTime(PatrolCheckPlanBean planBean) {
        String cycleType = planBean.getCycleType();
        String cycleUnit = planBean.getCycleUnit();
        //按周期固定
        if (StringUtils.isNotBlank(cycleType) && CycleType.CYCLE.getValue().equals(cycleType)) {
            if (StringUtils.isNotBlank(cycleUnit)) {
                //单位为时,前端给如00,01,02  后端转化为准确日期
                if (CycleUnit.H.getValue().equals(cycleUnit)) {
                    String result = new SimpleDateFormat("yyyy-MM-dd").format(new Date()) + " " + planBean.getWeekOrHourStartTime() + ":00:00";
                    try {
                        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(result);
                    } catch (ParseException e) {
                        log.error("日期格式错误");
                        e.printStackTrace();
                    }
                } else if (CycleUnit.W.getValue().equals(cycleUnit)) {
                    return dayOfWeek(planBean.getWeekOrHourStartTime());
                }
            }
        }
        return planBean.getPlanStartTime();
    }

    /**
     * 获取当前周周几的具体日期
     * day 周日: 1  周一: 2
     */
    private Date dayOfWeek(String day) {
        //传入时间做转换
        int original = Integer.parseInt(day);
        if (original == 1) {
            original = 7;
        } else {
            original = original - 1;
        }
        // 当前是周几，周日：1， 周一：2  ...
        int currDayOfWeek = DateUtil.dayOfWeek(new Date());
        //当前时间做转换
        if (currDayOfWeek == 1) {
            currDayOfWeek = 7;
        } else {
            currDayOfWeek = currDayOfWeek - 1;
        }
        //传入的时间和当前日期比较,传入日期在当前日期之后向后移动,反之向前
        int gap = original - currDayOfWeek;
        return DateUtil.beginOfDay(DateUtil.offsetDay(new Date(), gap).toJdkDate());
    }

    /**
     * 将前端传入的时间段数组(String)转为字符串 以 , 分割
     *
     * @param planBean
     * @return
     */
    private String getPlanPeriod(PatrolCheckPlanBean planBean) {
        List<String> periodList = planBean.getPeriod();
        String periodStr = null;
        if (CollectionUtil.isNotEmpty(periodList)) {
            periodStr = periodList.stream().map(String::new).collect(Collectors.joining(SPLIT_COMMA));
        }
        return periodStr;
    }

    /**
     * 将前端传入的userId数组转为字符串
     *
     * @return
     */
    private String getPlanCheckUserIds(PatrolCheckPlanBean planBean) {
        List<Long> checkUserIds = planBean.getCheckUserIds();
        String userStr = null;
        if (CollectionUtil.isNotEmpty(checkUserIds)) {
            userStr = checkUserIds.stream().map(Object::toString).collect(Collectors.joining(SPLIT_COMMA));
        }
        return userStr;
    }

    /**
     * 根据计划的周期设置获取计划的周期描述
     *
     * @param planBean
     * @return
     */
    private String getPlanCycleDesc(PatrolCheckPlanBean planBean) {
        //周期类型
        CycleType cycleType = CycleType.find(planBean.getCycleType());
        //周期单位
        CycleUnit cycleUnit = CycleUnit.find(planBean.getCycleUnit());
        String patrolCycle = null;
        switch (cycleType) {
            //按照固定周期
            case CYCLE:
                patrolCycle = String.format("%s%s一次", planBean.getFrequencyInterval(), cycleUnit.getDesc());
                break;
            //指定次数
            case SPECIFY:
                patrolCycle = String.format("每%s%s次(指定时间)", cycleUnit.getDesc(), planBean.getFrequencyInterval());
                break;
            //单次临时
            case SINGLE:
                Date planStartTime = planBean.getPlanStartTime();
                Date planEndTime = planBean.getPlanEndTime();
                DateFormat dateFormat = SimpleDateFormatCache.getYmdhm();
                String startTime = dateFormat.format(planStartTime);
                String endTime = dateFormat.format(planEndTime);
                patrolCycle = String.format("%s - %s", startTime, endTime);
                break;
        }
        return patrolCycle;
    }

    /**
     * 获取计划允许的补检时间
     *
     * @param planBean
     * @return
     */
    private Integer getPlanAllowRepairTime(PatrolCheckPlanBean planBean) {
        //开关未打开,不允许补检
        Integer result = 0;
        String allowRepair = planBean.getAllowRepair();
        //允许补检保存提前时间
        if (Constant.COMMON_SWITCH_ON.equals(allowRepair)) {
            //不是自定义的
            if (planBean.getSupplementaryInspectionTime() != -1) {
                //前端会将选择的时间转换为以分钟为单位给我们
                result = planBean.getSupplementaryInspectionTime();
            } else {
                //如果是-1则表示为自定义时间 以时为单位,转为分钟单位方便后期做任务
                result = planBean.getCustomizeSupplementaryInspection() * 60;
            }
        }
        return result;
    }

    /**
     * 新增计划时保存异常报警列表
     *
     * @param planId                  计划id
     * @param exceptionNotifyBeanList 异常通知列表
     */
    private void saveForExceptionNotify(Long planId, List<PatrolPlanExceptionNotifyBean> exceptionNotifyBeanList) {
        List<PatrolExceptionNotify> notifyList = new ArrayList<>();
        for (PatrolPlanExceptionNotifyBean bean : exceptionNotifyBeanList) {
            PatrolExceptionNotify notify = new PatrolExceptionNotify();
            notify.setPlanId(planId)
                    .setTriggerCondition(bean.getTriggerCondition())
                    .setAlarmTemplateId(bean.getAlarmTemplateId());
            notifyList.add(notify);
        }
        patrolExceptionNotifyService.saveBatch(notifyList);
    }

    /**
     * @param planId                       计划id
     * @param patrolCheckPlanPointBeanList 检查点列表
     */
    private void saveForCheckPoint(Long planId, List<PatrolCheckPlanPointBean> patrolCheckPlanPointBeanList) {
        List<PatrolPlanPointMapping> patrolPlanPointMappingList = new ArrayList<>();
        for (PatrolCheckPlanPointBean bean : patrolCheckPlanPointBeanList) {
            PatrolPlanPointMapping planPointMapping = new PatrolPlanPointMapping();
            planPointMapping.setPlanId(planId)
                    .setCheckPointId(bean.getCheckPointId())
                    .setOrderNo(bean.getOrderNo());
            patrolPlanPointMappingList.add(planPointMapping);
        }
        patrolPlanPointMappingService.saveBatch(patrolPlanPointMappingList);
    }

    @Override
    public void updatePlan(PatrolCheckPlanBean planBean) throws ApiBusinessException {
        //查看除了本身外有没有重复的名称
        Long tenentId = Context.getCurrentTenantId();
        String orgCode = Context.getCurrentOrgCode();
        Long count = patrolCheckPlanMapper.judgeForNameExcludeSelf(planBean.getId(), planBean.getCheckPlanName(), tenentId, orgCode);
        if (0 != count) {
            throw new ApiBusinessException(Status.CHECK_PLAN_NAME_REPEAT, planBean.getCheckPlanName());
        }
        //修改检查计划将原先的检查计划禁用以及计划下的检查点关系表删除,已经生成的任务继续按照原先任务规则进行
        deletePlanAndMapping(planBean.getId());
        //重新保存一份数据
        saveAgain(planBean);
    }

    /**
     * @param planId
     */
    private void deletePlanAndMapping(Long planId) {
        //将原先计划禁用,在分页查找时也不会查出来
        patrolCheckPlanMapper.disabledByPlanId(planId);
        //将计划与检查点之间的关系表也删除disabledByPlanId,不用删除,计划修改后，已经生成的任务还是按照原先计划配置去做任务
        //patrolPlanPointMappingMapper.disabledByPlanId(planId);
    }

    /**
     * 将计划重新保存,版本号加一,unique_id不变
     * 检查点列表也重新保存
     *
     * @param planBean
     */
    private void saveAgain(PatrolCheckPlanBean planBean) {
        PatrolCheckPlan oldPlan = patrolCheckPlanMapper.selectById(planBean.getId());
        String uniqueId = oldPlan.getBatchNo();
        Long planVersion = oldPlan.getPlanVersion() + 1;
        Long newPlanId = saveAgainForPlan(planBean, uniqueId, planVersion);
        saveForCheckPoint(newPlanId, planBean.getPatrolCheckPlanPointBeanList());
    }

    /**
     * 重新保存计划
     *
     * @param planBean
     * @param uniqueId
     * @param planVersion
     * @return
     */
    private Long saveAgainForPlan(PatrolCheckPlanBean planBean, String uniqueId, Long planVersion) {
        PatrolCheckPlan plan = new PatrolCheckPlan();
        plan.setPlanName(planBean.getCheckPlanName())
                .setCheckTypeId(planBean.getCheckTypeId())
                .setResponsibleDept(planBean.getResponsibleDept())
                .setCycleType(planBean.getCycleType())
                .setCycleUnit(planBean.getCycleUnit())
                .setFrequencyInterval(planBean.getFrequencyInterval())
                .setPlanEndTime(planBean.getPlanEndTime())
                .setExceptionNotify(planBean.getExceptionNotify())
                .setAllowRepair(planBean.getAllowRepair())
                .setOrderCheck(planBean.getOrderCheck())
                .setSignAdvance(planBean.getSignAdvance())
                .setAdvanceTime(planBean.getAdvanceTime())
                .setPatrolMode(planBean.getPatrolMode())
                .setPushTaskNow(planBean.getPushTaskNow())
                .setStatus(Constant.COMMON_SWITCH_ON)
                .setPlanVersion(planVersion)
                .setBatchNo(uniqueId)
                .setDeviceStopAutoProcess(planBean.getDeviceStopAutoProcess());
        //获取开始时间
        Date planStartTime = getPlanStartTime(planBean);
        plan.setPlanStartTime(planStartTime);
        //将前端传入的时间段转为string保存
        String planPeriod = getPlanPeriod(planBean);
        plan.setPeriod(planPeriod);

        String planCheckUserIds = getPlanCheckUserIds(planBean);
        plan.setCheckUserIds(planCheckUserIds);

        Integer planAllowRepairTime = getPlanAllowRepairTime(planBean);
        plan.setSupplementaryInspectionTime(planBean.getSupplementaryInspectionTime());
        plan.setCustomizeSupplementaryInspection(planBean.getCustomizeSupplementaryInspection());
        plan.setDelayMinute(planAllowRepairTime);

        String planCycleDesc = getPlanCycleDesc(planBean);
        plan.setCycleDesc(planCycleDesc);
        int id = patrolCheckPlanMapper.insert(plan);
        return plan.getId();
    }


    @Override
    public ResultBean checkPlanPage(Integer page, Integer size, String nameOrCode, Long responsibleDeptId, String statusName) {
        Long tenentId = Context.getCurrentTenantId();
        String orgCode = Context.getCurrentOrgCode();
        Page pageDtoPage = new Page(page, size);
        //加权限
        Set<Long> authDepartIds = baseRoleDataAuthService.findAuthDepartIdsByCurUser();
        if (CollectionUtil.isEmpty(authDepartIds)) {
            return ResultBean.pageData(new ArrayList<>(), 0);
        }
        Page<CheckPlanPageDto> resultPage = patrolCheckPlanMapper.selectListByPage(pageDtoPage, tenentId, orgCode, nameOrCode, authDepartIds, responsibleDeptId, statusName);
        if (CollectionUtil.isNotEmpty(resultPage.getRecords())) {
//            List<CheckPlanPageVo> voList = new ArrayList<>();
//            for (CheckPlanPageDto record : resultPage.getRecords()) {
//                CheckPlanPageVo checkPlanPageVo = convertForPlanPage(record);
//                voList.add(checkPlanPageVo);
//            }
            List<CheckPlanPageVo> voList= convertForPlanList(resultPage.getRecords());
            return ResultBean.pageData(voList, resultPage.getTotal());
        }
        return ResultBean.pageData(new ArrayList<>(), resultPage.getTotal());
    }

    /**
     * 将数据库查出的数据转换为前端需要的格式
     *
     * @param dto 数据库格式
     * @return 前端需要的格式
     */
    private CheckPlanPageVo convertForPlanPage(CheckPlanPageDto dto) {
        CheckPlanPageVo result = new CheckPlanPageVo();
        if (StringUtils.isNotBlank(dto.getStatus())) {
            result.setStatusName(Constant.COMMON_SWITCH_ON.equals(dto.getStatus()) ? "开启" : "关闭");
        }
        result.setId(dto.getId());
        result.setCheckPlanName(dto.getCheckPlanName());
        result.setStatus(dto.getStatus());
        result.setCycleDesc(dto.getCycleDesc());
        result.setResponsibleDeptName(dto.getResponsibleDept());
        //从关系表中查找检查计划下的检查点位数量
        Long pointNum = patrolPlanPointMappingService.getNumByPlanId(dto.getId());
        result.setPointNum(pointNum);
        return result;
    }

    private List<CheckPlanPageVo> convertForPlanList(List<CheckPlanPageDto> dtos) {
        List<CheckPlanPageVo> list=new ArrayList<>();
        if (CollectionUtils.isEmpty(dtos)) {
            return null;
        }
        List<Long> ids = dtos.stream().map(r -> r.getId()).collect(Collectors.toList());
        List<ResultDto> beans = patrolPlanPointMappingService.getNumByPlanIds(ids);
        Map<Long, ResultDto> map = beans.stream().collect(Collectors.toMap(ResultDto::getId, e -> e));
        for (CheckPlanPageDto dto : dtos) {
            CheckPlanPageVo result = new CheckPlanPageVo();
            if (StringUtils.isNotBlank(dto.getStatus())) {
                result.setStatusName(Constant.COMMON_SWITCH_ON.equals(dto.getStatus()) ? "开启" : "关闭");
            }
            result.setId(dto.getId());
            result.setCheckPlanName(dto.getCheckPlanName());
            result.setStatus(dto.getStatus());
            result.setCycleDesc(dto.getCycleDesc());
            if (CycleType.SINGLE.getValue().equals(dto.getCycleType())) {
                PatrolCheckPlanBean bean = new PatrolCheckPlanBean();
                bean.setCycleType(dto.getCycleType());
                bean.setPlanEndTime(dto.getPlanEndTime());
                bean.setPlanStartTime(dto.getPlanStartTime());
                // 允许补检，截止时间增加
                if ("1".equals(dto.getAllowRepair()) && dto.getSupplementaryInspectionTime() != null) {
                    Date endTime = DateUtil.offsetMinute(dto.getPlanEndTime(), dto.getSupplementaryInspectionTime());
                    bean.setPlanEndTime(endTime);
                }
                // 允许提前，截止时间减少
                if ("1".equals(dto.getSignAdvance()) && dto.getAdvanceTime() != null) {
                    Date startTime = DateUtil.offsetMinute(dto.getPlanStartTime(), -dto.getAdvanceTime());
                    bean.setPlanStartTime(startTime);
                }
                result.setCycleDesc(getPlanCycleDesc(bean));
            }
            result.setResponsibleDeptName(dto.getResponsibleDept());
            if (map.get(dto.getId())!=null&&map.get(dto.getId()).getNum()!=null) {
                result.setPointNum(map.get(dto.getId()).getNum().longValue());
            }
            list.add(result);
        }

        return list;
    }

    @Override
    public CheckPlanDetailVo getPlanDetailById(Long planId) {
        Long tenentId = Context.getCurrentTenantId();
        String orgCode = Context.getCurrentOrgCode();
        //查找对应的检查计划
        PatrolCheckPlan planDetail = patrolCheckPlanMapper.getPlanDetailById(tenentId, orgCode, planId);
        return convertForPlanDetail(planDetail);
    }

    /**
     * 将数据库的格式转换为前端需要的数据
     *
     * @param planDetail
     * @return
     */
    private CheckPlanDetailVo convertForPlanDetail(PatrolCheckPlan planDetail) {
        CheckPlanDetailVo result = new CheckPlanDetailVo();
        result.setId(planDetail.getId());
        result.setCheckPlanName(planDetail.getPlanName());

        //检查类型名称(数据字典维护)
        String planTypeName = baseTypeGroupItemService.findNameById(planDetail.getCheckTypeId());
        result.setCheckTypeId(planDetail.getCheckTypeId());
        result.setCheckTypeName(planTypeName);

        //时段
        String cycleType = planDetail.getCycleType();
        String period = planDetail.getPeriod();
        String cycleUnit = planDetail.getCycleUnit();
        if (CycleType.SPECIFY.getValue().equals(cycleType) && StringUtils.isNotBlank(period)) {
            List<String> periodList = Splitter.on(SPLIT_COMMA).trimResults().splitToList(period).stream().map(String::new).collect(Collectors.toList());
            if (CycleUnit.D.getValue().equals(cycleUnit)) {
                List<String> periodList1 = new ArrayList<>();
                //指定次数并且为天时,前端存入  1-2 ， 2-3 ， 5-6  展示为 01:00-02:00 , 02:00-03:00 , 05:00-06:00
                for (String s : periodList) {
                    String[] split = s.split("-");
                    String start = split[0];
                    String end = split[1];
                    if (1 == start.length()) {
                        start = String.format("0%s:00", start);
                    } else {
                        start = String.format("%s:00", start);
                    }
                    if (1 == end.length()) {
                        end = String.format("0%s:00", end);
                    } else {
                        end = String.format("%s:00", end);
                    }
                    String resultStr = start + "-" + end;
                    periodList1.add(resultStr);
                }
                result.setPeriod(periodList1);
            } else {
                result.setPeriod(periodList);
            }
        }
        //责任部门
        String departName = bpDepartDao.getNameById(planDetail.getResponsibleDept());
        result.setResponsibleDept(planDetail.getResponsibleDept());
        result.setResponsibleDeptName(departName);

        //当周期类型为固定次数,且周期单位为 周 或者 时 的时候,将计划开始时间转为前端需要的数据
        String specialField = getSpecialField(planDetail);
        result.setWeekOrHourStartTime(specialField);

        //检查人员
        String checkUserIds = planDetail.getCheckUserIds();
        if (StringUtils.isNotBlank(checkUserIds)) {
            List<Long> ids = Splitter.on(SPLIT_COMMA).trimResults().splitToList(checkUserIds).stream().map(Long::new).collect(Collectors.toList());
            List<SimpleListBean> userList = new ArrayList<>();
            for (Long id : ids) {
                SimpleListBean listBean = new SimpleListBean();
                String realName = baseUserDao.getRealNameById(id);
                listBean.setId(id);
                listBean.setName(realName);
                userList.add(listBean);
            }
            result.setUserList(userList);
        }
        result.setCycleType(planDetail.getCycleType());
        result.setCycleUnit(planDetail.getCycleUnit());
        result.setFrequencyInterval(planDetail.getFrequencyInterval());
        result.setPlanStartTime(planDetail.getPlanStartTime());
        result.setPlanEndTime(planDetail.getPlanEndTime());
        result.setExceptionNotify(planDetail.getExceptionNotify());
        result.setAllowRepair(planDetail.getAllowRepair());
        result.setSupplementaryInspectionTime(planDetail.getSupplementaryInspectionTime());
        result.setCustomizeSupplementaryInspection(planDetail.getCustomizeSupplementaryInspection());
        result.setOrderCheck(planDetail.getOrderCheck());
        result.setSignAdvance(planDetail.getSignAdvance());
        result.setPatrolMode(planDetail.getPatrolMode());
        result.setAdvanceTime(planDetail.getAdvanceTime());
        result.setPushTaskNow(planDetail.getPushTaskNow());
        result.setStatus(planDetail.getStatus());
        result.setDeviceStopAutoProcess(planDetail.getDeviceStopAutoProcess());
        //报警列表

        //检查点列表
        List<CheckPlanDetailPointVo> planPointByPlanIdList = findPlanPointByPlanId(planDetail.getId());
        result.setCheckPlanDetailPointVoList(planPointByPlanIdList);
        return result;
    }

    /**
     * 当周期类型为固定次数,且周期单位为 周 或者 时 的时候,将计划开始时间转为前端需要的数据
     *
     * @param plan
     * @return
     */
    private String getSpecialField(PatrolCheckPlan plan) {
        String cycleType = plan.getCycleType();
        String cycleUnit = plan.getCycleUnit();
        //按周期固定
        Date planStartTime = plan.getPlanStartTime();
        if (StringUtils.isNotBlank(cycleType) && CycleType.CYCLE.getValue().equals(cycleType)) {
            if (StringUtils.isNotBlank(cycleUnit)) {
                //单位为时,前端给如00,01,02  后端转化为准确日期,返回前端时同理
                if (CycleUnit.H.getValue().equals(cycleUnit)) {
                    int hour = DateUtil.hour(planStartTime, true);
                    return hour < 10 ? "0" + hour : "" + hour;
                } else if (CycleUnit.W.getValue().equals(cycleUnit)) {
                    int dayOfWeek = DateUtil.dayOfWeek(planStartTime);
                    return dayOfWeek + "";
                }
            }
        }
        return null;
    }


    /**
     * 根据计划id查询检查点
     *
     * @param planId
     * @return
     */
    private List<CheckPlanDetailPointVo> findPlanPointByPlanId(Long planId) {
        List<CheckPlanDetailPointVo> planCheckPointList = patrolCheckPointService.findPlanPointByPlanId(planId);
        for (CheckPlanDetailPointVo vo : planCheckPointList) {
            if (StringUtils.isNotBlank(vo.getStatus())) {
                vo.setStatusName(Constant.COMMON_SWITCH_ON.equals(vo.getStatus()) ? "启用" : "禁用");
            }
            vo.setPlanId(planId);
            //根据检查点查看一个检查点下有多少个项目
            Long checkItemNum = patrolCheckItemService.findCheckItemNumByPointId(vo.getCheckPointId());
            vo.setCheckItemNum(checkItemNum);
            //根据检查点查看一个检查点下有多少个设备
            Long equipmentNum = patrolCheckItemService.findEquipmentNumByPointId(vo.getCheckPointId());
            vo.setEquipmentNum(equipmentNum);
        }
        return planCheckPointList;
    }

    @Override
    public ResultBean closeOrOpenPlan(Long id, String flag) {
        patrolCheckPlanMapper.closeOrOpenPlan(id, flag);
        return ResultBean.defaultSuccessResult();
    }

    @Override
    public ResultBean deletePlanById(Long id) {
        patrolCheckPlanMapper.deletePlanById(id);
        //删除检查计划与检查点之间的关系表数据,无需删除关系表,删除计划已经生成的任务继续按照原来的规则去做
        return ResultBean.defaultSuccessResult();
    }

    @Override
    public Map<String, List<Long>> getPlanNameIdMapping(String planName) {
        Long tenantId = Context.getCurrentTenantId();
        String orgCode = Context.getCurrentOrgCode();
        List<KeyValueVO<String, String>> allNameAndIdGroup = patrolCheckPlanMapper.listAllNameAndIdGroup(tenantId, orgCode, planName);
        if (CollectionUtil.isEmpty(allNameAndIdGroup)) {
            return Collections.emptyMap();
        }
        Map<String, List<Long>> result = new HashMap<>();

        allNameAndIdGroup.forEach(each -> {
            List<Long> planIds = Arrays.asList(each.getValue().split(SPLIT_COMMA)).stream().map(Long::valueOf).collect(Collectors.toList());
            result.put(each.getKey(), planIds);
        });

        return result;

    }

    @Override
    public String getNameByTaskId(Long taskId) {
        return patrolCheckPlanMapper.selectNameByTaskId(taskId);
    }
    @Override
    public List<String> getAllName() {
        Long tenentId = Context.getCurrentTenantId();
        String orgCode = Context.getCompanyCode();
        return patrolCheckPlanMapper.selectAllName(tenentId, orgCode);
    }
    @Override
    public List<String> getAllByName(String planName) {
        Long tenentId = Context.getCurrentTenantId();
        String orgCode = Context.getCompanyCode();
        return patrolCheckPlanMapper.selectAllByName(tenentId, orgCode,planName);
    }
}
